/* * * Copyright 2017: Robert Winkler * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package io.github.resilience4j.circuitbreaker; import java.time.Duration; import java.util.function.Supplier; import io.github.resilience4j.core.StopWatch; import io.vertx.core.Future; /** * CircuitBreaker decorators for Vert.x */ public interface VertxCircuitBreaker { /** * Decorates and executes the decorated Future. * * @param circuitBreaker the CircuitBreaker * @param supplier the Future Supplier * @param <T> the type of results returned by this Future * @return a future which is decorated by a CircuitBreaker. */ static <T> Future<T> executeFuture(CircuitBreaker circuitBreaker, Supplier<Future<T>> supplier){ return decorateFuture(circuitBreaker, supplier).get(); } /** * Returns a Future which is decorated by a CircuitBreaker. * * @param circuitBreaker the CircuitBreaker * @param supplier the Future supplier * @param <T> the type of the returned Future's result * @return a future which is decorated by a CircuitBreaker. */ static <T> Supplier<Future<T>> decorateFuture(CircuitBreaker circuitBreaker, Supplier<Future<T>> supplier){ return () -> { final Future<T> future = Future.future(); if (!circuitBreaker.isCallPermitted()) { future.fail( new CircuitBreakerOpenException( String.format("CircuitBreaker '%s' is open", circuitBreaker.getName()))); } else { long start = System.nanoTime(); try { supplier.get().setHandler(result -> { long durationInNanos = System.nanoTime() - start; if (result.failed()) { circuitBreaker.onError(durationInNanos, result.cause()); future.fail(result.cause()); } else { circuitBreaker.onSuccess(durationInNanos); future.complete(result.result()); } }); } catch (Throwable throwable) { long durationInNanos = System.nanoTime() - start; circuitBreaker.onError(durationInNanos, throwable); future.fail(throwable); } } return future; }; } }